package cn.com.cetccst.uploadlog;

import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class FileUtils {
    private static final String TAG = "FileUtils";

    public static void gzipFolder(File src, File dst) {
        try {
            if (dst.exists()) {
                dst.delete();
            }
            File tempDst = new File(getGzipFileName(dst.getAbsolutePath()));
            zipFolder(src, tempDst);
            gzipFile(tempDst, dst, true);
        } catch (Exception e) {
            Logger.log(Log.ERROR, TAG, "gzipFolder: ", e);
        }
    }

    private static String getGzipFileName(String zipFilename) {
        if (!TextUtils.isEmpty(zipFilename) && zipFilename.endsWith(".gzip")) {
            return zipFilename.replace(".gzip", ".zip");
        }
        return zipFilename;
    }

    public static void gzipFile(File srcFile, File dstFile) {
        try {
            gzipFile(srcFile, dstFile, true);
        } catch (IOException e) {
            Logger.log(Log.ERROR, TAG, "gzipFile: ", e);
        }
    }

    public static void gzipFile(File srcFile, File desFile, boolean isDeleteSrc) throws IOException {
        GZIPOutputStream zos = null;
        FileInputStream fis = null;
        try {
            zos = new GZIPOutputStream(new FileOutputStream(desFile));
            fis = new FileInputStream(srcFile);
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = (fis.read(buffer))) != -1) {
                zos.write(buffer, 0, len);
            }
        } finally {
            if (zos != null) {
                zos.close();
            }
            if (fis != null) {
                fis.close();
            }
            if (isDeleteSrc) {
                srcFile.delete();
            }
        }
    }

    public static void zipFolder(File srcFile, File zipFile) throws Exception {
        ZipOutputStream outZip = null;
        try {
            if (zipFile.exists()) {
                zipFile.delete();
            }
            outZip = new ZipOutputStream(new FileOutputStream(zipFile));
            zipFiles(srcFile.getParent() + File.separator, srcFile.getName(), outZip);
        } finally {
            if (outZip != null) {
                outZip.finish();
                outZip.close();
            }
        }
    }

    private static void zipFiles(String folderPath, String filePath,
                                 ZipOutputStream zipOut) throws Exception {
        if (zipOut == null) {
            return;
        }

        File file = new File(folderPath + filePath);

        if (file.isFile()) {
            ZipEntry zipEntry = new ZipEntry(filePath);
            FileInputStream inputStream = new FileInputStream(file);
            zipOut.putNextEntry(zipEntry);

            int len;
            byte[] buffer = new byte[4096];

            while ((len = inputStream.read(buffer)) != -1) {
                zipOut.write(buffer, 0, len);
            }

            zipOut.closeEntry();
        } else {
            String fileList[] = file.list();

            if (fileList.length <= 0) {
                ZipEntry zipEntry =
                        new ZipEntry(filePath + File.separator);
                zipOut.putNextEntry(zipEntry);
                zipOut.closeEntry();
            }

            for (int i = 0; i < fileList.length; i++) {
                zipFiles(folderPath, filePath + File.separator + fileList[i], zipOut);
            }
        }
    }

    public static void copyFileUsingFileChannels(File source, File dest)
            throws IOException {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(dest).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            inputChannel.close();
            outputChannel.close();
        }
    }
}
